package com.doit.day02

import com.doit.day01.Student

import scala.collection.mutable.ArrayBuffer

object _05_函数的本质 {
  def main(args: Array[String]): Unit = {

    println(add) //com.doit.day02._05_函数的本质$$$Lambda$1/1534030866@1d251891
    println(add(1, 2)) //代表对象调用了app方法，传进去了两个参数，1,2 返回一个int类型的3给你
    val student: Student = new Student()
    val stu1 = student
    student.setId(1)
    val a: (Int, Int) => Int = add
    val b: Int = a(1, 2)


    //第二个就要传一个具体的函数对象进去了
    val fun = (a:Int,b:Int)=>{
      (c:Int)=>{a+b+c}
    }


    val intToInt: Int => Int = res1("jingjing", fun)
    val i: Int = intToInt(4)

  }


  //add 是个啥：Function2这个接口的实现类对象
  //(a:Int,b:Int) 这是Function2这个接口中抽象方法apply方法的参数列表
  //{ a + b } 这是apply方法的方法体
  //刚才也看了，函数的类型就是Function2
  //函数的类型：java的写法 Function2[Int,Int,Int]  ==> (Int, Int) => Int   (Int, Int)= Int
  // 有更加简单的语法糖的写法，你为啥不写   alt + 回车   万能修复键
  val add: (Int, Int) => Int = (a: Int, b: Int) => {
    a + b
  }


  val sayHi = (name: String) => {
    println(s"${name},我们都好想你")
  }


  // Function3[Int,Int,Int,Int]
  // (Int,Int,Int) => Int
  val getMin :(Int,Int,Int) => Int = (a: Int, b: Int, c: Int) => {
    var min = a
    if (b < min) min = b
    if (c < min) min = c
    min
  }

  //Function0[Unit]   ==>   ()=>{}   ()=> 类型
  val hehe :()=> Unit = ()=>{
    println("晶晶大坏蛋")
  }


  //:(Student,Int) => Student
  val aaa  :(Student,Int) => Unit = (stu:Student,a:Int)=>{
    //这是一个表达式   表达式如果在最后一行，返回值就是 Unit
    val student: Student = new Student()
    //他也是一个表达式，他是一个Unit类型
    println(student)
  }


  /*
      函数中传了两个参数进去
      第一个参数是一个函数 传进去一个Int类型，传出来一个Int类型
      第二个参数是int类型

      返回值类型，op(a)  ==> 执行了这个函数，得到一个Int类型的结果

      (Int)=>Int
   */


  // (Int=>Int,Int)=>Int
  val biandan:((Int)=>Int,Int)=>Int = (op:Int=>Int,a:Int)=> {
    op(a)
  }



  (stu:Student)=>{
    new Student()
  }

  //函数高阶的应用
  /*
    String
    (Int,String)=>Int)=>Int  这个函数不得了，穿进去一个Int，一个String 返回了一个Int=>Int的函数
    函数可以当做参数传递,可以当做返回值返回



   */
  val res1 = (op:String,a:(Int,Int)=>(Int)=>Int)=>{
    a(1,2)
  }

















  /*  def min(b:Int*)={
      //怎么取到里面最小的那个
      val arr: ArrayBuffer[Int] = new ArrayBuffer[Int]()
      //    arr.append(a)
      //b是一个可变参数，那么b里面可能是一个，可能是多个，甚至可能没有，将b自动的转换成集合
      for (elem <- b) {
        arr.append(elem)
      }
      //按照剩下排列
      /*
          val sorted: ArrayBuffer[Int] = arr.sorted
          val min: ArrayBuffer[Int] = sorted.take(1)
          min*/
      arr.min
      /*    arr.max
          arr.sum
          arr.sum/arr.length    */
    }*/


  /* val min1 = (b: Int*) => {
     //怎么取到里面最小的那个
     val arr: ArrayBuffer[Int] = new ArrayBuffer[Int]()
     //    arr.append(a)
     //b是一个可变参数，那么b里面可能是一个，可能是多个，甚至可能没有，将b自动的转换成集合
     for (elem <- b) {
       arr.append(elem)
     }
     //按照剩下排列
     /*
         val sorted: ArrayBuffer[Int] = arr.sorted
         val min: ArrayBuffer[Int] = sorted.take(1)
         min*/
     arr.min
     /*    arr.max
         arr.sum
         arr.sum/arr.length    */
   }*/

}
